using System;
using System.Collections.Generic;
using System.Linq;

namespace Pogo.Data
{
   internal class Service : PogoObject, IFileService
   {
      private RestService serviceConnection;
      internal string DeviceID { get; set; }
      internal string ServiceID { get; set; }

      internal string SClass { get; set; }
      internal string Type { get; set; }
      internal bool MsgPending { get; set; }
      internal string ApiURL { get; set; }
      internal string Space { get; set; }
      internal int Flags { get; set; }

      internal RestService ServiceConnection
      {
         get { return serviceConnection ?? (serviceConnection = new RestService(ApiURL)); }
      }

      internal bool HasFiles
      {
         get { return Type.StartsWith("xce:plugfs"); }
      }

      #region IFileService Members

      public IDevice Device
      {
         get { return Root.Devices.First(d => ((Device) d).DeviceID == DeviceID); }
      }

      public string Name { get; set; }
      public string Version { get; set; }
      public bool Online { get; set; }
      public bool OnLAN { get; set; }

      public int GetFileCount(bool includeHidden)
      {
         return GetFileCount(null, includeHidden);
      }

      public DirectoryListing GetFiles(FileOptions options)
      {
         return GetFiles(options, null);
      }

      public IEnumerable<DirectoryEntry> FindFiles(string criteria, FileOptions options = null)
      {
         return FindFiles(criteria, options, null);
      }

      public bool Update(string newName)
      {
         throw new NotImplementedException();
      }

      public void Upload(string path, byte[] contents)
      {
         throw new NotImplementedException();
      }

      #endregion

      internal IEnumerable<DirectoryEntry> FindFiles(string criteria, FileOptions options, string parentID)
      {
         throw new NotImplementedException();
      }

      internal DirectoryListing GetFiles(FileOptions options, string parentID)
      {
         options = options ?? new FileOptions();
         int maxCount = (options.MaxCount == 0 ? GetFileCount(parentID, options.ShowHidden) : options.MaxCount);
         DirectoryListing list = ServiceConnection.ListFiles<DirectoryListing>(AuthToken, DeviceID, ServiceID, parentID,
                                                               options.ShowHidden, options.Page, maxCount,
                                                               options.SortString);
         list.Parent = this;

         foreach (DirectoryEntry file in list.Files)
         {
            file.Parent = this;
            file.ParentDevice = (Device) Root.Devices.First(d => ((Device) d).DeviceID == DeviceID);
            file.ParentService = this;
         }

         return list;
      }

      internal int GetFileCount(string parentID, bool includeHidden)
      {
         DirectoryListing list = ServiceConnection.ListFiles<DirectoryListing>(AuthToken, DeviceID, ServiceID, parentID, includeHidden,
                                                               0, 1);
         return list.TotalCount;
      }

      internal DirectoryEntry GetFile(FileIdentifierType identifierType, string identifier)
      {
         string parameterName = null;

         switch (identifierType)
         {
            case FileIdentifierType.Path:
               parameterName = "path";
               break;
            case FileIdentifierType.FileID:
               parameterName = "fileid";
               break;
         }

         DirectoryEntry directoryEntry = ServiceConnection.GetFile<DirectoryEntry>(AuthToken, DeviceID, ServiceID, parameterName, identifier);

         directoryEntry.Parent = this;
         directoryEntry.ParentDevice = (Device) Root.Devices.First(d => ((Device) d).DeviceID == DeviceID);
         directoryEntry.ParentService = this;

         return directoryEntry;
      }
   }
}